package com.wasion.pwportable.jsi;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import jxl.Workbook;
import jxl.write.Label;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;

import org.json.JSONException;
import org.json.JSONObject;

import android.R.string;
import android.content.Context;
import android.webkit.WebView;

import com.google.gson.Gson;
import com.wasion.core.config.Config;
import com.wasion.core.db.Pagination;
import com.wasion.core.db.storage.SqliteStorage;
import com.wasion.core.db.storage.SqliteStorageListener.DataInsertListener;
import com.wasion.core.db.storage.SqliteStorageListener.DataQueryListener;
import com.wasion.core.db.storage.SqliteStorageListener.DataUpdateListener;
import com.wasion.core.db.storage.StorageQuery;
import com.wasion.core.db.storage.StorageQuery.SortOrder;
import com.wasion.core.util.DateTimeUtil;
import com.wasion.core.util.StringUtil;
import com.wasion.pwportable.activity.PwPortableActivity;
import com.wasion.pwportable.dao.sd.IndicatorSDDBDao;
import com.wasion.pwportable.dao.sd.TerminalSDDBDao;
import com.wasion.pwportable.dao.sd.WorkLineSDDBDao;
import com.wasion.pwportable.domain.po.Terminal;
import com.wasion.pwportable.domain.po.WorkLine;

/**
 * 
 * @ClassName: TerminalJSI
 * @Description: 终端JavaScriptInterface，对终端操作交互接口<br/>
 *               1. 增加/修改终端 <br/>
 *               2. 删除终端 <br/>
 *               3. 获取终端 <br/>
 * @author 高意
 * @date 2014-8-1 下午2:57:06
 * 
 */
public class TerminalJSI {

	// 应用上下文
	private Context context;

	// webview，浏览器窗口
	private WebView webView;

	// Sqlite存储实例
	private SqliteStorage sqliteStorage = null;

	// Google的Json转换工具
	private Gson gson = new Gson();

	// 终端数据库访问接口
	private TerminalSDDBDao terminalSDDBDao = null;

	// 默认的SVG内容
	private static String DEFAULT_SVG_CONTENT;

	Terminal terminal = new Terminal();

	// 终端地址
	private String terminalAddr;

	// 终端ID
	private String terminalId;

	// 无线模块地址
	private String wirelessAddr;

	// SVG内容
	private String svgContent;

	// 是否点击查询按钮触发事件
	private boolean isQuery;

	static {
		StringBuffer buffer = new StringBuffer();
		buffer.append("<svg id=\"worksvg\" style=\"width: 100%;\" ");
		buffer.append("xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">");
		buffer.append("<defs>");
		buffer.append("<linearGradient id=\"selectedgradient\" x1=\"100%\" y1=\"0%\" x2=\"0%\" y2=\"100%\">");
		buffer.append("<stop offset=\"10%\" style=\"stop-color:rgb(255,240,0)\"/>");
		buffer.append("<stop offset=\"100%\" style=\"stop-color:rgb(255,0,0);\"/></linearGradient>");
		buffer.append("<marker id=\"markerArrow\" viewBox=\"0 0 10 10\" refX=\"0\" refY=\"5\" markerUnits=\"strokeWidth\" markerWidth=\"3\" markerHeight=\"10\" orient=\"auto\">");
		buffer.append("<path d=\"M 0 0 L 10 5 L 0 10 z\" fill=\"#ffffff\" stroke=\"gray\"/></marker>");
		buffer.append("</defs>");
		buffer.append("</svg>");

		DEFAULT_SVG_CONTENT = buffer.toString();
	}

	public TerminalJSI(Context context) {
		this.context = context;
		this.webView = PwPortableActivity.getWebView();
		this.sqliteStorage = SqliteStorage.getInstance(this.context);
		terminalSDDBDao = new TerminalSDDBDao(context);
	}

	/**
	 * 
	 * @Title: addOrModifyTerminal
	 * @Description: 新增/修改终端
	 * @param
	 * @return
	 * @throws
	 */
	public void addOrModifyTerminal(final String jsonStr) {

		terminal = gson.fromJson(jsonStr, Terminal.class);
		terminal.setTime(DateTimeUtil.getCurrentDate());

		terminalAddr = terminal.getTerminaladdr().toUpperCase();
		wirelessAddr = terminal.getWirelessaddr().toUpperCase();
		terminalId = terminal.get_id() + "";

		terminal.setTerminaladdr(terminalAddr);
		terminal.setWirelessaddr(wirelessAddr);

		StorageQuery storageQuery = new StorageQuery();
		storageQuery.equals("wirelessaddr", terminal.getWirelessaddr());
		storageQuery.equals("terminaladdr", terminal.getTerminaladdr());
		if (0 == terminal.get_id()) { // 为0，新增

			sqliteStorage.findData(storageQuery, terminalSDDBDao,
					new DataQueryListener() {

						public void onFailure(int errorCode, String errorMessage) {
							JSIHelper.showToast(context, "添加失败!");
						}

						public void onSuccess(List<?> paramList) {

							if (null != paramList && 0 < paramList.size()) {
								JSIHelper.showToast(context,
										"终端地址已存在, 不能重复添加!");
								return;
							}

							terminal.setSvgcontent(DEFAULT_SVG_CONTENT); // 默认的SVG内容
							sqliteStorage.insertData(terminal, terminalSDDBDao,
									new DataInsertListener() {

										public void onSuccess(long paramLong) {
											if (0 == paramLong) {
												JSIHelper.showToast(context,
														"添加失败!");
												return;
											}

											JSIHelper.showToast(context,
													"添加成功!");
											Map<String, Object> map = new HashMap<String, Object>();
											map.put("type", "terminal");
											map.put("terminalAddr",
													terminalAddr);
											map.put("terminalId", terminalId);
											map.put("wirelessAddr",
													wirelessAddr);

											String result = gson.toJson(map);
											webView.loadUrl("javascript:editSuccessCallback("
													+ result + ")");
										}

										public void onFailure(int errorCode,
												String errorMessage) {
											JSIHelper.showToast(context,
													"添加失败!");
										}
									});
						}
					});

		} else { // 修改

			storageQuery.notEqual("_id", terminal.get_id());
			sqliteStorage.findData(storageQuery, terminalSDDBDao,
					new DataQueryListener() {

						public void onFailure(int errorCode, String errorMessage) {
							JSIHelper.showToast(context, "修改失败!");
						}

						public void onSuccess(List<?> paramList) {

							if (null != paramList && 0 < paramList.size()) {
								JSIHelper.showToast(context,
										"终端地址已存在, 不能重复添加!");
								return;
							}

							sqliteStorage.updateData(terminal, terminalSDDBDao,
									new DataUpdateListener() {

										public void onSuccess(long paramLong) {

											if (0 == paramLong) {
												JSIHelper.showToast(context,
														"修改失败!");
												return;
											}

											JSIHelper.showToast(context,
													"修改成功!");
											Map<String, Object> map = new HashMap<String, Object>();
											map.put("type", "terminal");
											map.put("terminalAddr",
													terminalAddr);
											map.put("terminalId", terminalId);
											map.put("wirelessAddr",
													wirelessAddr);

											String result = gson.toJson(map);
											webView.loadUrl("javascript:editSuccessCallback("
													+ result + ")");
										}

										public void onFailure(int errorCode,
												String errorMessage) {
											JSIHelper.showToast(context,
													"修改失败!");
										}
									});
						}
					});
		}
	}

	/**
	 * 
	 * @Title: removeTerminal
	 * @Description: 删除终端
	 * @param
	 * @return
	 * @throws
	 */
	public void removeTerminal(final String _id) {

		if (StringUtil.isEmpty(_id)) {
			JSIHelper.showToast(context, "终端唯一标识不能为空!");
			return;
		}

		StorageQuery storageQuery = new StorageQuery();
		storageQuery.equals("terminalid", _id);

		sqliteStorage.findData(storageQuery, new IndicatorSDDBDao(context),
				new DataQueryListener() {

					public void onFailure(int errorCode, String errorMessage) {
						JSIHelper.showToast(context, "删除终端失败!");
					}

					public void onSuccess(List<?> paramList) {

						if (null != paramList && 0 < paramList.size()) {
							JSIHelper.showToast(context, "终端下存在指示器, 不能删除!");
							webView.loadUrl("javascript:removePauseCallback()");
							return;
						}

						StorageQuery sq = new StorageQuery();
						sq.equals("_id", Integer.parseInt(_id));

						sqliteStorage.deleteData(sq, terminalSDDBDao,
								new DataUpdateListener() {

									public void onSuccess(long paramLong) {
										Map<String, Object> map = new HashMap<String, Object>();
										map.put("success", true);
										map.put("type", "terminal");
										map.put("terminalId", _id);

										String result = gson.toJson(map);
										JSIHelper.showToast(context, "删除成功!");
										webView.loadUrl("javascript:removeSuccuessCallback("
												+ result + ")");
									}

									public void onFailure(int errorCode,
											String errorMessage) {
										JSIHelper.showToast(context, "删除失败!");
									}
								});
					}
				});

	}

	/**
	 * 
	 * @Title: queryTerminals
	 * @Description: 获取终端
	 * @param
	 * @return
	 * @throws
	 */
	public void queryTerminals(final String jsonStr) {

		PwPortableActivity.getHandler().post(new Runnable() {
			public void run() {
				Terminal terminal = new Terminal();
				terminal = gson.fromJson(jsonStr, Terminal.class);

				StorageQuery storageQuery = new StorageQuery();

				int _id = terminal.get_id();
				if (0 != _id) {
					storageQuery.equals("_id", _id);
				}

				terminalSDDBDao.startReadableDatabase(false);
				List<Terminal> terminals = terminalSDDBDao.queryList(
						new String[] { "_id", "terminaladdr", "wirelessaddr",
								"lineid", "location" },
						storageQuery.getWhereClause(),
						storageQuery.getWhereArgs(), null, null, "time desc",
						null);
				terminalSDDBDao.closeDatabase(false);

				if (null != terminals && 0 < terminals.size()) {
					try {
						String result = gson.toJson(terminals);

						webView.loadUrl("javascript:loadTerminals(" + result
								+ ")");
					} catch (Exception e) {
						JSIHelper.showToast(context, e.getMessage());
					}
				}
			}
		});
	}

	/**
	 * 
	 * @Title: queryTerminalsByPage
	 * @Description: 分页获取终端
	 * @param
	 * @return
	 * @throws
	 */
	public void queryTerminalsByPage(final String jsonStr) {

		PwPortableActivity.getHandler().post(new Runnable() {

			public void run() {

				try {
					JSONObject jsObj = new JSONObject(jsonStr);
					isQuery = jsObj.getBoolean("isQuery");
				} catch (JSONException e1) {
					e1.printStackTrace();
				}

				List<Terminal> terminals = listTerminal(jsonStr);

				if (isQuery && (null == terminals || 0 == terminals.size())) {
					String jsonStr = gson.toJson(terminals);

					webView.loadUrl("javascript:queryTerminalsByPageCallback("
							+ jsonStr + ")");
					return;
				}

				if (null != terminals && 0 < terminals.size()) {
					try {
						String result = gson.toJson(terminals);

						webView.loadUrl("javascript:queryTerminalsByPageCallback("
								+ result + ")");
					} catch (Exception e) {
						JSIHelper.showToast(context, e.getMessage());
					}
				} else {
					JSIHelper.showToast(context, "已加载所有终端!");
				}
			}
		});
	}

	/**
	 * 
	 * @Title: listTerminal
	 * @Description: 根据条件查询的终端
	 * @param
	 * @return
	 * @throws
	 */
	protected List<Terminal> listTerminal(String jsonStr) {

		StorageQuery storageQuery = new StorageQuery();
		try {

			JSONObject jsObj = new JSONObject(jsonStr);
			
			if (!jsObj.isNull("pId")) {
				storageQuery.equals("lineid", jsObj.getString("pId"));
			}
			if (!jsObj.isNull("terminaladdr")) {
				storageQuery.like("upper(terminaladdr)",
						jsObj.getString("terminaladdr").toUpperCase());
			}

			int size = Pagination.DEFAULT_PAGE_SIZE;
			if (!jsObj.isNull("pagesize")) {
				storageQuery.setLimit(Integer.parseInt(jsObj
						.getString("pagesize")));
			} else {
				storageQuery.setLimit(Pagination.DEFAULT_PAGE_SIZE);
			}

			if (!jsObj.isNull("page")) {
				storageQuery.setOffset(size
						* (Integer.parseInt(jsObj.getString("page")) - 1));
			} else {
				storageQuery.setOffset(size * (Pagination.DEFAULT_PAGE - 1));
			}

			storageQuery.addSort("time", SortOrder.DESC);
		} catch (JSONException e1) {
			e1.printStackTrace();
		}

		terminalSDDBDao.startReadableDatabase(false);
		List<Terminal> terminals = terminalSDDBDao.queryList(new String[] {
				"_id", "terminaladdr", "wirelessaddr", "location", "lineid",
				"time" }, storageQuery.getWhereClause(),
				storageQuery.getWhereArgs(), null, null,
				storageQuery.getOrderBy() + " limit " + storageQuery.getLimit()
						+ " offset " + storageQuery.getOffset(), null);
		terminalSDDBDao.closeDatabase(false);

		if (null != terminals && 0 < terminals.size()) {
			for (Terminal t : terminals) {
				String lineId = t.getLineid();

				WorkLineSDDBDao workLineSDDBDao = new WorkLineSDDBDao(context);
				workLineSDDBDao.startReadableDatabase(false);
				List<WorkLine> workLines = workLineSDDBDao.queryList(
						new String[] { "linename" }, "_id=?",
						new String[] { lineId + "" }, null, null, null, null);
				workLineSDDBDao.closeDatabase(false);

				t.setLinename(workLines.get(0).getLinename());
			}
		}

		return terminals;
	}

	/**
	 * 
	 * @Title: getSVGContent
	 * @Description: 获取终端对应的SVG内容
	 * @param
	 * @return
	 * @throws
	 */
	public void getSVGContent(final String jsonStr) {

		PwPortableActivity.getHandler().post(new Runnable() {
			public void run() {
				Terminal terminal = new Terminal();
				terminal = gson.fromJson(jsonStr, Terminal.class);

				StorageQuery storageQuery = new StorageQuery();

				int _id = terminal.get_id();
				if (0 != _id) {
					storageQuery.equals("_id", _id);
				}

				terminalSDDBDao.startReadableDatabase(false);
				List<Terminal> terminals = terminalSDDBDao.queryList(
						new String[] { "_id", "terminaladdr", "wirelessaddr",
								"lineid", "svgcontent" },
						storageQuery.getWhereClause(),
						storageQuery.getWhereArgs(), null, null, null, null);
				terminalSDDBDao.closeDatabase(false);

				if (null != terminals && 0 < terminals.size()) {
					try {
						String result = gson.toJson(terminals.get(0));

						webView.loadUrl("javascript:tapTerminalCallback("
								+ result + ")");
					} catch (Exception e) {
						JSIHelper.showToast(context, e.getMessage());
					}
				}
			}
		});
	}

	/**
	 * 
	 * @Title: saveSVGContent
	 * @Description: 保存终端对应的SVG内容
	 * @param
	 * @return
	 * @throws
	 */
	public void saveSVGContent(final String terminalid,
			final String svgcontent, final String mode) {

		PwPortableActivity.getHandler().post(new Runnable() {
			public void run() {

				if (StringUtil.isEmpty(terminalid) && "4".endsWith(mode)) { // 在没有打开SVG图形时，直接退出
					webView.goBack();
					return;
				}

				svgContent = svgcontent.replace(
						"href=\"../../image/t1800d.jpg\"",
						"xlink:href=\"../../image/t1800d.jpg\""); // 特殊处理，svg存储的时候地址转成了href，而svg中资源都是基于xlink:href

				Terminal terminal = new Terminal();
				terminal.set_id(Integer.parseInt(terminalid));
				terminal.setSvgcontent(svgContent);
				terminal.setTime(DateTimeUtil.getCurrentDate());

				sqliteStorage.updateData(terminal, terminalSDDBDao,
						new DataUpdateListener() {

							public void onSuccess(long paramLong) {
								if ("1".equals(mode)) {
									JSIHelper.showToast(context, "图形保存成功!");
								} else if ("4".equals(mode)) {
									webView.goBack();
									return;
								}
							}

							public void onFailure(int errorCode,
									String errorMessage) {
								if ("1".equals(mode)) {
									JSIHelper.showToast(context, "图形保存失败!");
								} else if ("4".equals(mode)) {
									JSIHelper.showToast(context, "保存图形发生异常!");
								}
							}
						});
			}
		});
	}

	/**
	 * 
	 * @Title: exportTerminals
	 * @Description: 导出终端信息
	 * @param
	 * @return
	 * @throws
	 */
	public void exportTerminals(String jsonStr) {

		try {
			/*
			 * String path = Export.getSDPath() + "/" + Config.EXPORT_PATH +
			 * "/terminal/";
			 */
			String path = "";
			String fileName = DateTimeUtil.getCurrentDate("yyyyMMddHHmmss")
					+ ".xls";

			File usbDirectory = new File(Export.getUDiskPath());
			if (usbDirectory.exists() && usbDirectory.isDirectory()
					&& usbDirectory.canWrite()) {
				path = Export.getUDiskPath() + "/" + Config.EXPORT_PATH
						+ "/terminal/";

			} else {
				path = Export.getSDPath() + "/" + Config.EXPORT_PATH
						+ "/terminal/";
			}

			File directory = new File(path);
			if (!directory.exists() && !directory.isDirectory()) {
				directory.mkdirs();
			}

			File file = new File(path + fileName);
			if (!file.exists()) {
				file.createNewFile();
			}

			// 创建一个可写入的工作薄(Workbook)对象
			WritableWorkbook workBook = Workbook.createWorkbook(file);

			if (workBook != null) {
				// 第一个参数是工作表的名称，第二个是工作表在工作薄中的位置
				WritableSheet sheet = workBook.createSheet("终端", 0);

				// 设置表名和表头的行高
				sheet.setRowView(0, 800);
				sheet.setRowView(1, 600);

				// 设置列宽
				sheet.setColumnView(0, 10);
				sheet.setColumnView(1, 18);
				sheet.setColumnView(2, 18);
				sheet.setColumnView(3, 30);
				sheet.setColumnView(4, 30);
				sheet.setColumnView(5, 25);

				// 合并单元格，在指定单元格插入表名
				sheet.mergeCells(0, 0, 5, 0);
				sheet.addCell(new Label(0, 0, "终端信息表", Export
						.getTitleCellFormat()));

				// 在指定单元格插入表头
				sheet.addCell(new Label(0, 1, "序号", Export
						.getHeaderCellFormat()));
				sheet.addCell(new Label(1, 1, "终端地址", Export
						.getHeaderCellFormat()));
				sheet.addCell(new Label(2, 1, "无线模块地址", Export
						.getHeaderCellFormat()));
				sheet.addCell(new Label(3, 1, "安装位置", Export
						.getHeaderCellFormat()));
				sheet.addCell(new Label(4, 1, "所属线路", Export
						.getHeaderCellFormat()));
				sheet.addCell(new Label(5, 1, "时间", Export
						.getHeaderCellFormat()));

				// 在接下来的内容中插入数据
				List<Terminal> terminals = listTerminal(jsonStr);
				for (int i = 0; i < terminals.size(); i++) {
					Terminal terminal = terminals.get(i);
					int row = 2 + i;
					sheet.addCell(new Label(0, row, terminal.get_id() + "",
							Export.getBodyCellFormat()));
					sheet.addCell(new Label(1, row, terminal.getTerminaladdr(),
							Export.getBodyCellFormat()));
					sheet.addCell(new Label(2, row, terminal.getWirelessaddr(),
							Export.getBodyCellFormat()));
					sheet.addCell(new Label(3, row, terminal.getLocation(),
							Export.getBodyCellFormat()));
					sheet.addCell(new Label(4, row, terminal.getLinename(),
							Export.getBodyCellFormat()));
					sheet.addCell(new Label(5, row, terminal.getTime(), Export
							.getBodyCellFormat()));
				}

				// 从内存中写入文件中
				workBook.write();
				workBook.close();

				JSIHelper.showToast(context, "终端导出成功!");
			}
		} catch (Exception e) {
			e.printStackTrace();
			JSIHelper.showToast(context, "导出终端发生异常!");
		}
	}
	
	/**
	 * 
	 * @Title: modifyTerminalAddr
	 * @Description: 修改终端地址
	 * @param
	 * @return
	 * @throws
	 */
	public void modifyTerminalAddr(final String terminalId,
			final String newTerminalAddr) {
		PwPortableActivity.getHandler().post(new Runnable() {
			public void run() {
				try {

					TerminalSDDBDao SDDBDao = new TerminalSDDBDao(
							context);
					SDDBDao.startReadableDatabase(false);
					SDDBDao
							.execSql(
									"update terminal set terminaladdr=? where _id=?",
									new String[] { newTerminalAddr.toUpperCase(),
											terminalId });

					SDDBDao.closeDatabase(false);

					Map<String, Object> resultMap = new HashMap<String, Object>();
					resultMap.clear();
					resultMap.put("success", true);
					resultMap.put("terminaladdr", newTerminalAddr);
					String result = gson.toJson(resultMap);

					webView.loadUrl("javascript:modifyTerminalAddrCallback("
							+ result + ")");
				} catch (Exception e) {
					JSIHelper.showToast(context, "修改终端失败!");
				}
			}
		});
	}
}
